import { divide, round } from 'number-precision';

import convertTothousandths from './convertTothousandths';

/**
 * toYuan的选项
 * @interface IToYuanOptions
 */
interface IToYuanOptions {
  /** 保留几位小数，默认为2 */
  decimal?: number;
  /** 是否只显示必要的小数,比如5.00将显示为5,5.10将显示为5.1，默认为false */
  decimalIfNeeded?: boolean;
  /** 是否千分位 */
  thousandCentimeter?: boolean;
  /** 千分位符号 */
  thousandCentimeterSeparator?: string;
}

/**
 * 分转化成元，分一般为整数，但该方法也支持小数。
 * 0.105.toFixed(2) 返回的是 0.1 而不是 0.11，所以不用toFixed
 * @export
 * @since 1.0.1
 * @example
 * toYuan(100) // 1.00
 * @param {(number | string)} num 分,不一定是整数
 * @param {IToYuanOptions} [options={}] 选项
 * @param {number} [options.decimal=2] 保留几位小数，默认为2
 * @param {boolean} [options.decimalIfNeeded=false] 是否只显示必要的小数,比如5.00将显示为5,5.10将显示为5.1，默认为false
 * @param {boolean} [options.thousandCentimeter=false] 是否千分位
 * @param {string} [options.thousandCentimeterSeparator=','] 千分位符号
 * @return {string} 格式化后的字符串元
 */
export default function toYuan(
  num: number | string,
  {
    decimal = 2, thousandCentimeter = false, thousandCentimeterSeparator, decimalIfNeeded = false,
  }:IToYuanOptions = {},
):string {
  // 参数检查
  if (typeof num !== 'number' && typeof num !== 'string') {
    return '';
  }
  // 转换类型
  // eslint-disable-next-line no-param-reassign
  num = +num;
  let yuan:number | string = divide(num, 100);
  // 四舍五入,在这里yuan已经是字符串了
  yuan = `${round(yuan, decimal)}`;
  // decimalIfNeeded为true的话，5.00将显示为5，5.10将显示为5.1;否则按照精度保留足够的0
  if (!decimalIfNeeded) {
    // 已有的小数
    const decimalPart = yuan.split('.')[1] || '';
    // 小数的长度
    const decimalPartLength = decimalPart.length;
    // 还差几个0
    const needZeroLength = decimal - decimalPartLength;
    // 如果少个小数点，则加上
    if (!decimalPartLength && needZeroLength > 0) {
      yuan = `${yuan}.`;
    }
    // 补足needZeroLength个0
    if (needZeroLength > 0) {
      yuan = `${yuan}${'0'.repeat(needZeroLength)}`;
    }
  }
  // 千分位
  if (thousandCentimeter) {
    yuan = convertTothousandths(yuan, {
      separator: thousandCentimeterSeparator,
    });
  }

  return yuan;
}
